<?php
class UserManager
{
    private $firstName = '';
    private $lastName = '';
    private $email = '';
    private $password = '';
    private $sex = '';
    private $birthday = '';

    public function __construct()
    {
    }

    private function initializeUser()
    {
        $this->firstName = DataBase::getInstance()->quote( $_POST['first_name'] );
        $this->lastName  = DataBase::getInstance()->quote( $_POST['last_name'] );
        $this->email     = DataBase::getInstance()->quote( $_POST['email'] );
        $this->reEmail   = DataBase::getInstance()->quote( $_POST['re_email'] );
        $this->password  = DataBase::getInstance()->quote( $_POST['password'] );
        $this->sex       = DataBase::getInstance()->quote( $_POST['sex'] );
        $this->birthday  = DataBase::getInstance()->quote( $_POST['year'] . '-' . $_POST['month'] . '-' . $_POST['day'] );
    }

    private function getInfoFromDataBase()
    {
        $query = DataBaseProvider::getUserInfoByEmail( $this->email );
        $resultArray = DataBase::getInstance()->query( $query );
        if ( empty( $resultArray ) )
        {
            throw new Exception( 'This user does not exist.' );
        }
        $this->firstName = $resultArray[0]['first_name'];
        $this->lastName  = $resultArray[0]['last_name'];
        $this->password  = $resultArray[0]['pass'];
        $this->sex       = $resultArray[0]['sex'];
        $this->birthday  = $resultArray[0]['birthday'];
    }

    private function getInfo()
    {
        $userInfoArray  = array
        (
            'first_name' => $this->firstName,
            'last_name'  => $this->lastName,
            'email'      => $this->email,
            'password'   => $this->password,
            'sex'        => $this->sex,
            'birthday'   => $this->birthday
        );
        
        return $userInfoArray;
    }
    
    /**
     * The method allows to check whether the user is registered by mail and password.
     * If no parameters are specified, it will e-mail here from the array $_POST.
     * 
     * @param email     User E-Mail.
     * @param password  User Password.
     * 
     * @return boolean.
     */
    public function isUserExist( $email = NULL, $password = NULL )
    {
        if ( !$email && !$password )
        {
            $email = $_POST['email'];
        }
        $query  = DataBaseProvider::generateFindUserQuery( $email, $password );     
        $result = DataBase::getInstance()->query( $query );
        if ( empty( $result ) )
        {
            return false;
        }
        return true;
    }

    private function checkRegistrationError()
    {
        if ( $this->isUserExist() )
        {
            throw new Exception( 'This E-Mail is already registered!' );
        }        
    }

    private function checkSearchErrors()
    {
        if ( ( !isset( $_POST['email'] ) ) || ( empty( $_POST['email'] ) ) )
        {
            throw new Exception( 'E-Mail field is empty!' );
        }
        $this->email = DataBase::getInstance()->quote( $_POST['email'] );
    }

    /**
     * The method load user by his e-mail, sent by method POST.
     * 
     * @return array with user information in format TemplateEngine.
     */
    public function loadUserByEmail()
    {
        $this->checkSearchErrors();
        $this->getInfoFromDataBase();
        return $this->getInfo();
    }
    
    /**
     * The method load user by his user_id, sent by method GET.
     * 
     * @return array with user information in format TemplateEngine.
     */
    public function loadUserById()
    {
        $userInfoArray = array();
        if ( isset( $_GET['id'] ) && !empty( $_GET['id'] ) )
        {
            $selectResult = '';
            $id = (int)$_GET['id'];
            $query = DataBaseProvider::getUserById( $id );
            $selectResult = DataBase::getInstance()->query( $query );
            if ( !empty( $selectResult ) )
            {
                $userInfoArray = array
                (
                    'first_name' => $selectResult[0]['first_name'],
                    'last_name'  => $selectResult[0]['last_name'],
                    'email'      => $selectResult[0]['email'],
                    'password'   => $selectResult[0]['pass'],
                    'sex'        => $selectResult[0]['sex'],
                    'birthday'   => $selectResult[0]['birthday']
                );
            }
            else
            {
                throw new Exception( 'This user does not exist.' );
            }
        }
        return $userInfoArray;
    }
    
    /**
     * The method save user in database. If the user is not saved, will throw an exception.
     * Information sent in form by method POST.
     * 
     * @throws RuntimeException    Throw exception, if for some reason could not save.
     * 
     * @return sting-message about successful save.
     */
    public function saveUser()
    {
        $this->checkRegistrationError();
        $this->initializeUser();
        $query = DataBaseProvider::generateSaveUserQuery
        (
            $this->firstName,
            $this->lastName,
            $this->email,
            $this->password,
            $this->sex,
            $this->birthday
        );
        DataBase::getInstance()->query( $query );
        return "Congratulations! Now you can enter the site.";
    }
    
    private function pagesCalculation( $page, &$totalPages )
    {
        $query = DataBaseProvider::countUsers();
        $selectResult = DataBase::getInstance()->query( $query );
        $allUsers = $selectResult[0]['COUNT(*)'];
        
        $totalPages = intval( $allUsers / USERS_ON_PAGE );
        if ( $allUsers % USERS_ON_PAGE )
        {
            ++$totalPages;
        }
        if ( $page <= 0 )
        {
            $page = 1;
        }
        if ( $page > $totalPages )
        {
            $page = $totalPages;
        }
        $start = $page * USERS_ON_PAGE - USERS_ON_PAGE;
        
        return $start;
    }
    
    /**
     * The method takes a set of users from database who will be on specific page of the list of users.
     * 
     * @param page          The current page that you want to display the users.
     * @param totalPages    The variable that you want to count the total number of pages.
     * 
     * @return array of users for current page or empty array, if page is wrong.
     */
    public function getRangeOfUsers( $page,  &$totalPages )
    {
        $start = $this->pagesCalculation( $page, $totalPages );
        $query = DataBaseProvider::usersRangeQuery( $start );
        return DataBase::getInstance()->query( $query );
    }
}
?>